package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.CountsVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.UserInfoTVO;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.service.*;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author げっしょく
 * @date 2021/11/2
 */
@Service
public class UsersService {

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private MessagesService messagesService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    public PageResult getLookMe(Integer page, Integer pagesize, String nickname) {
        //当前用户id
        Long userId = UserHolder.getId();


        String key = Constants.VISITORS_USER;
        String hashKey = userId.toString();
        //添加用户上一次查看时间
        Long l = System.currentTimeMillis();
//        redisTemplate.opsForHash().put(key, hashKey, l.toString());

        //获得访问过我的用户并判断是否为空
        List<Visitors> list = visitorsApi.getPageLookMe(page, pagesize, userId);
        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //取出访问过我用户的id
        List<Long> visitorUserId = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        //通过id找出我对ta是否喜欢
        Map<Long, UserLike> map = userLikeApi.getLikes(visitorUserId, userId);
        //通过id找出用户详情
        UserInfo userInfo = new UserInfo();
        if (!StringUtils.isEmpty(nickname)) {
            userInfo.setNickname(nickname);
        }
        Map<Long, UserInfo> byUserIds = userInfoApi.getByUserIds(visitorUserId, userInfo);
        //通过id找出我与对方的缘分值
        Map<Long, RecommendUser> re = recommendUserApi.getUsers(visitorUserId, userId);
        //遍历集合
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long id : visitorUserId) {
            UserInfo userInfo1 = byUserIds.get(id);
            if (userInfo1 != null) {
                UserLike userLike = map.get(id);
                Boolean isLike = false;
                if (!ObjectUtil.isEmpty(userLike)) {
                    isLike = userLike.getIsLike();
                }
                RecommendUser recommendUser = re.get(id);
                Double score = RandomUtil.randomDouble(60.0, 95.6);
                if (ObjectUtil.isNotEmpty(recommendUser)) {
                    score = recommendUser.getScore();
                }

                UserInfoTVO vo = UserInfoTVO.init(userInfo1, isLike, score);
                vos.add(vo);
            }
        }
        return new PageResult(page, pagesize, 0L, vos);
    }

    //从redis中查询我喜欢的用户id
//    public


    //查询相互喜欢
    public PageResult getLikeMutually(Integer page, Integer pagesize, String nickname) {
        Set<String> members = getLikeUserIds();
        //判断从reids中取出来的数据是否为空
        if (CollUtil.isEmpty(members)) {
            return new PageResult();
        }
        //遍历set集合
        List<Long> userIds = members.stream().map(m -> Long.valueOf(m)).collect(Collectors.toList());
        //通过用户set集合去查找喜欢我的并返回
        List<UserLike> likes = userLikeApi.getWhoLoveMe(userIds, UserHolder.getId());
        //判断找到的数据是否为空
        if (CollUtil.isEmpty(likes)) {
            return new PageResult();
        }
        //取出数据(喜欢我的)中的用户id
        List<Long> userLikes = likes.stream().map(like -> like.getUserId()).collect(Collectors.toList());
        //通过用户id和条件去查询用户信息
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(userLikes, userInfo);
        //通过用户id去查询和我缘分值
        Map<Long, RecommendUser> users = recommendUserApi.getUsers(userIds, UserHolder.getId());
        //调用方法封装数据
        return getPageResult(page, pagesize, userLikes, map, users);
    }

    //用户封装我喜欢和互相喜欢的数据
    private PageResult getPageResult(Integer page, Integer pagesize, List<Long> userLikes, Map<Long, UserInfo> map, Map<Long, RecommendUser> users) {
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long userLike : userLikes) {
            UserInfo userInfo = map.get(userLike);
            if (userInfo != null) {
                RecommendUser recommendUser = users.get(userLike);
                Double score = null;
                if (recommendUser != null) {
                    score = recommendUser.getScore();
                } else {
                    score = RandomUtil.randomDouble(60.5, 89.6);
                }
                UserInfoTVO vo = UserInfoTVO.init(userInfo, true, score);
                vos.add(vo);
            }
        }
        //封装数据
        return new PageResult(page, pagesize, Long.valueOf(vos.size()), vos);
    }

    //从redis中获取我喜欢的用户id
    private Set<String> getLikeUserIds() {
        //从redis中查询出我喜欢的用户
        String key = Constants.USER_LIKE_KEY + UserHolder.getId();
        return redisTemplate.opsForSet().members(key);
    }

    //查看我喜欢的
    public PageResult getMeLikeWho(Integer page, Integer pagesize, String nickname) {
        //从redis中读取我喜欢的用户id
        Set<String> likeUserIds = getLikeUserIds();
        if (CollUtil.isEmpty(likeUserIds)) {
            return new PageResult();
        }
        List<Long> userIds = likeUserIds.stream().map(u -> Long.valueOf(u)).collect(Collectors.toList());
        //通过用户查询用户详情
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setNickname(nickname);
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(userIds, userInfo1);
        //通过用户id查询我和他缘分值
        Map<Long, RecommendUser> users = recommendUserApi.getUsers(userIds, UserHolder.getId());
        //查询我是否喜欢他(省略: 因为从redis中取出来的都是喜欢的)
        //封装数据并返回
        return getPageResult(page, pagesize, userIds, map, users);

    }

    //查看谁喜欢我
    public PageResult getWhoLikeMe(Integer page, Integer pagesize, String nickname) {
        //通过redis获取我喜欢的用户
        Set<String> likeUserIds = getLikeUserIds();
        List<Long> userIds = new ArrayList<>();
        if (likeUserIds != null) {
            userIds = likeUserIds.stream().map(id -> Long.valueOf(id)).collect(Collectors.toList());
        }
        //通过数据库获取喜欢我的用户
        List<UserLike> likeMe = userLikeApi.getLikeMe(UserHolder.getId());
        //获取喜欢的用户的id
        if (CollUtil.isEmpty(likeMe)) {
            return new PageResult();
        }
        List<Long> likeMeUserIds = likeMe.stream().map(like -> like.getUserId()).collect(Collectors.toList());
        //获取喜欢我用户的详细信息
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setNickname(nickname);
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(likeMeUserIds, userInfo1);
        //查找我与他的缘分值
        Map<Long, RecommendUser> users = recommendUserApi.getUsers(likeMeUserIds, UserHolder.getId());
        //封装数据, 返回集合
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long likeIds : likeMeUserIds) {
            UserInfo userInfo = map.get(likeIds);
            if (userInfo != null) {
                RecommendUser recommendUser = users.get(likeIds);
                Double score = 0D;
                if (recommendUser != null) {
                    score = recommendUser.getScore();
                } else {
                    score = RandomUtil.randomDouble(60D, 90D);
                }
                //判断在我喜欢的用户id中有没有喜欢我的用户id,如果有就是我喜欢
                UserInfoTVO vo = UserInfoTVO.init(userInfo, userIds.contains(likeIds), score);
                vos.add(vo);
            }
        }

        return new PageResult(page, pagesize, Long.valueOf(vos.size()), vos);
    }

    //对粉丝进行喜欢
    public void fans(Long likeUserId) {
        //获取当前用户id
        Long userId = UserHolder.getId();
        //在数据库中添加一条数据
        Boolean aBoolean = userLikeApi.saveOrUpdate(userId, likeUserId, true);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //在redis中添加喜欢数据
        SetOperations<String, String> setRedis = redisTemplate.opsForSet();
        setRedis.add(Constants.USER_LIKE_KEY + userId, likeUserId.toString());
        //从redis中获取数据进行判断他是否对我进行了喜欢
        if (redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY + likeUserId, userId.toString())) {
            //添加好友
            messagesService.addFriend(likeUserId);
        }
    }

    /**
     * 取消喜欢
     * @param likeUserId
     */
    public void deleteLikeUser(Long likeUserId) {
        //获得当前用户Id
        Long userId = UserHolder.getId();
        //调用方法删除数据库中存入的数据
        userLikeApi.deleteLikeUser(userId, likeUserId);
        //删除reids中的喜欢数据
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + userId, likeUserId.toString());
        //从redis中获取数据进行判断他是否对我进行了喜欢
        if (redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY + likeUserId, userId.toString())) {
            //如果喜欢了就删除好友
            messagesService.deleteFriend(likeUserId);
        }
    }
}
